 /*******************************************************************************
  * Copyright (c) 2000, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.ui.forms;

 import java.util.HashMap ;
 import java.util.Iterator ;
 import java.util.Map ;

 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.RGB;
 import org.eclipse.swt.widgets.Display;

 /**
  * Manages colors that will be applied to forms and form widgets. The colors are
  * chosen to make the widgets look correct in the editor area. If a different
  * set of colors is needed, subclass this class and override 'initialize' and/or
  * 'initializeColors'.
  *
  * @since 3.0
  */
 public class FormColors {
     /**
      * Key for the form title foreground color.
      *
      * @deprecated use <code>IFormColors.TITLE</code>.
      */
     public static final String TITLE = IFormColors.TITLE;

     /**
      * Key for the tree/table border color.
      *
      * @deprecated use <code>IFormColors.BORDER</code>
      */
     public static final String BORDER = IFormColors.BORDER;

     /**
      * Key for the section separator color.
      *
      * @deprecated use <code>IFormColors.SEPARATOR</code>.
      */
     public static final String SEPARATOR = IFormColors.SEPARATOR;

     /**
      * Key for the section title bar background.
      *
      * @deprecated use <code>IFormColors.TB_BG
      */
     public static final String TB_BG = IFormColors.TB_BG;

     /**
      * Key for the section title bar foreground.
      *
      * @deprecated use <code>IFormColors.TB_FG</code>
      */
     public static final String TB_FG = IFormColors.TB_FG;

     /**
      * Key for the section title bar gradient.
      *
      * @deprecated use <code>IFormColors.TB_GBG</code>
      */
     public static final String TB_GBG = IFormColors.TB_GBG;

     /**
      * Key for the section title bar border.
      *
      * @deprecated use <code>IFormColors.TB_BORDER</code>.
      */
     public static final String TB_BORDER = IFormColors.TB_BORDER;

     /**
      * Key for the section toggle color. Since 3.1, this color is used for all
      * section styles.
      *
      * @deprecated use <code>IFormColors.TB_TOGGLE</code>.
      */
     public static final String TB_TOGGLE = IFormColors.TB_TOGGLE;

     /**
      * Key for the section toggle hover color.
      *
      * @since 3.1
      * @deprecated use <code>IFormColors.TB_TOGGLE_HOVER</code>.
      */
     public static final String TB_TOGGLE_HOVER = IFormColors.TB_TOGGLE_HOVER;

     protected Map colorRegistry = new HashMap (10);

     protected Color background;

     protected Color foreground;

     private boolean shared;

     protected Display display;

     protected Color border;

     /**
      * Creates form colors using the provided display.
      *
      * @param display
      * the display to use
      */
     public FormColors(Display display) {
         this.display = display;
         initialize();
     }

     /**
      * Returns the display used to create colors.
      *
      * @return the display
      */
     public Display getDisplay() {
         return display;
     }

     /**
      * Initializes the colors. Subclasses can override this method to change the
      * way colors are created. Alternatively, only the color table can be
      * modified by overriding <code>initializeColorTable()</code>.
      *
      * @see #initializeColorTable
      */
     protected void initialize() {
         background = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
         foreground = display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
         initializeColorTable();
         updateBorderColor();
     }

     /**
      * Allocates colors for the following keys: BORDER, SEPARATOR and
      * TITLE. Subclasses can override to allocate these colors differently.
      */
     protected void initializeColorTable() {
         createTitleColor();
         createColor(IFormColors.SEPARATOR, getColor(IFormColors.TITLE).getRGB());
         RGB black = getSystemColor(SWT.COLOR_BLACK);
         RGB borderRGB = getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT);
         createColor(IFormColors.BORDER, blend(borderRGB, black, 80));
     }

     /**
      * Allocates colors for the section tool bar (all the keys that start with
      * TB). Since these colors are only needed when TITLE_BAR style is used with
      * the Section widget, they are not needed all the time and are allocated on
      * demand. Consequently, this method will do nothing if the colors have been
      * already initialized. Call this method prior to using colors with the TB
      * keys to ensure they are available.
      */
     public void initializeSectionToolBarColors() {
         if (colorRegistry.containsKey(IFormColors.TB_BG))
             return;
         createTitleBarGradientColors();
         createTitleBarOutlineColors();
         createTwistieColors();
     }

     /**
      * Allocates additional colors for the form header, namely background
      * gradients, bottom separator keylines and DND highlights. Since these
      * colors are only needed for clients that want to use these particular
      * style of header rendering, they are not needed all the time and are
      * allocated on demand. Consequently, this method will do nothing if the
      * colors have been already initialized. Call this method prior to using
      * color keys with the H_ prefix to ensure they are available.
      *
      * @since 3.3
      */
     protected void initializeFormHeaderColors() {
         if (colorRegistry.containsKey(IFormColors.H_BOTTOM_KEYLINE2))
             return;
         createFormHeaderColors();
     }

     /**
      * Returns the RGB value of the system color represented by the code
      * argument, as defined in <code>SWT</code> class.
      *
      * @param code
      * the system color constant as defined in <code>SWT</code>
      * class.
      * @return the RGB value of the system color
      */
     public RGB getSystemColor(int code) {
         return getDisplay().getSystemColor(code).getRGB();
     }

     /**
      * Creates the color for the specified key using the provided RGB object.
      * The color object will be returned and also put into the registry. When
      * the class is disposed, the color will be disposed with it.
      *
      * @param key
      * the unique color key
      * @param rgb
      * the RGB object
      * @return the allocated color object
      */
     public Color createColor(String key, RGB rgb) {
         return createColor(key, rgb.red, rgb.green, rgb.blue);
     }

     /**
      * Creates a color that can be used for areas of the form that is inactive.
      * These areas can contain images, links, controls and other content but are
      * considered auxilliary to the main content area.
      *
      * <p>
      * The color should not be disposed because it is managed by this class.
      *
      * @return the inactive form color
      * @since 3.1
      */
     public Color getInactiveBackground() {
         String key = "__ncbg__"; //$NON-NLS-1$
 Color color = getColor(key);
         if (color == null) {
             RGB sel = getSystemColor(SWT.COLOR_LIST_SELECTION);
             // a blend of 95% white and 5% list selection system color
 RGB ncbg = blend(sel, getSystemColor(SWT.COLOR_WHITE), 5);
             color = createColor(key, ncbg);
         }
         return color;
     }

     /**
      * Creates the color for the specified key using the provided RGB values.
      * The color object will be returned and also put into the registry. If
      * there is already another color object under the same key in the registry,
      * the existing object will be disposed. When the class is disposed, the
      * color will be disposed with it.
      *
      * @param key
      * the unique color key
      * @param r
      * red value
      * @param g
      * green value
      * @param b
      * blue value
      * @return the allocated color object
      */
     public Color createColor(String key, int r, int g, int b) {
         Color c = new Color(display, r, g, b);
         Color prevC = (Color) colorRegistry.get(key);
         if (prevC != null)
             prevC.dispose();
         colorRegistry.put(key, c);
         return c;
     }

     /**
      * Computes the border color relative to the background. Allocated border
      * color is designed to work well with white. Otherwise, stanard widget
      * background color will be used.
      */
     protected void updateBorderColor() {
         if (isWhiteBackground())
             border = getColor(IFormColors.BORDER);
         else {
             border = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
             Color bg = getImpliedBackground();
             if (border.getRed() == bg.getRed()
                     && border.getGreen() == bg.getGreen()
                     && border.getBlue() == bg.getBlue())
                 border = display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW);
         }
     }

     /**
      * Sets the background color. All the toolkits that use this class will
      * share the same background.
      *
      * @param bg
      * background color
      */
     public void setBackground(Color bg) {
         this.background = bg;
         updateBorderColor();
         updateFormHeaderColors();
     }

     /**
      * Sets the foreground color. All the toolkits that use this class will
      * share the same foreground.
      *
      * @param fg
      * foreground color
      */
     public void setForeground(Color fg) {
         this.foreground = fg;
     }

     /**
      * Returns the current background color.
      *
      * @return the background color
      */
     public Color getBackground() {
         return background;
     }

     /**
      * Returns the current foreground color.
      *
      * @return the foreground color
      */
     public Color getForeground() {
         return foreground;
     }

     /**
      * Returns the computed border color. Border color depends on the background
      * and is recomputed whenever the background changes.
      *
      * @return the current border color
      */
     public Color getBorderColor() {
         return border;
     }

     /**
      * Tests if the background is white. White background has RGB value
      * 255,255,255.
      *
      * @return <samp>true</samp> if background is white, <samp>false</samp>
      * otherwise.
      */
     public boolean isWhiteBackground() {
         Color bg = getImpliedBackground();
         return bg.getRed() == 255 && bg.getGreen() == 255
                 && bg.getBlue() == 255;
     }

     /**
      * Returns the color object for the provided key or <samp>null </samp> if
      * not in the registry.
      *
      * @param key
      * the color key
      * @return color object if found, or <samp>null </samp> if not.
      */
     public Color getColor(String key) {
         if (key.startsWith(IFormColors.TB_PREFIX))
             initializeSectionToolBarColors();
         else if (key.startsWith(IFormColors.H_PREFIX))
             initializeFormHeaderColors();
         return (Color) colorRegistry.get(key);
     }

     /**
      * Disposes all the colors in the registry.
      */
     public void dispose() {
         Iterator e = colorRegistry.values().iterator();
         while (e.hasNext())
             ((Color) e.next()).dispose();
         colorRegistry = null;
     }

     /**
      * Marks the colors shared. This prevents toolkits that share this object
      * from disposing it.
      */
     public void markShared() {
         this.shared = true;
     }

     /**
      * Tests if the colors are shared.
      *
      * @return <code>true</code> if shared, <code>false</code> otherwise.
      */
     public boolean isShared() {
         return shared;
     }

     /**
      * Blends c1 and c2 based in the provided ratio.
      *
      * @param c1
      * first color
      * @param c2
      * second color
      * @param ratio
      * percentage of the first color in the blend (0-100)
      * @return the RGB value of the blended color
      * @since 3.1
      */
     public static RGB blend(RGB c1, RGB c2, int ratio) {
         int r = blend(c1.red, c2.red, ratio);
         int g = blend(c1.green, c2.green, ratio);
         int b = blend(c1.blue, c2.blue, ratio);
         return new RGB(r, g, b);
     }

     /**
      * Tests the source RGB for range.
      *
      * @param rgb
      * the tested RGB
      * @param from
      * range start (excluding the value itself)
      * @param to
      * range end (excluding the value itself)
      * @return <code>true</code> if at least one of the primary colors in the
      * source RGB are within the provided range, <code>false</code>
      * otherwise.
      * @since 3.1
      */
     public static boolean testAnyPrimaryColor(RGB rgb, int from, int to) {
         if (testPrimaryColor(rgb.red, from, to))
             return true;
         if (testPrimaryColor(rgb.green, from, to))
             return true;
         if (testPrimaryColor(rgb.blue, from, to))
             return true;
         return false;
     }

     /**
      * Tests the source RGB for range.
      *
      * @param rgb
      * the tested RGB
      * @param from
      * range start (excluding the value itself)
      * @param to
      * tange end (excluding the value itself)
      * @return <code>true</code> if at least two of the primary colors in the
      * source RGB are within the provided range, <code>false</code>
      * otherwise.
      * @since 3.1
      */
     public static boolean testTwoPrimaryColors(RGB rgb, int from, int to) {
         int total = 0;
         if (testPrimaryColor(rgb.red, from, to))
             total++;
         if (testPrimaryColor(rgb.green, from, to))
             total++;
         if (testPrimaryColor(rgb.blue, from, to))
             total++;
         return total >= 2;
     }

     /**
      * Blends two primary color components based on the provided ratio.
      *
      * @param v1
      * first component
      * @param v2
      * second component
      * @param ratio
      * percentage of the first component in the blend
      * @return
      */
     private static int blend(int v1, int v2, int ratio) {
         int b = (ratio * v1 + (100 - ratio) * v2) / 100;
         return Math.min(255, b);
     }

     private Color getImpliedBackground() {
         if (getBackground() != null)
             return getBackground();
         return getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
     }

     private static boolean testPrimaryColor(int value, int from, int to) {
         return value > from && value < to;
     }

     private void createTitleColor() {
         /*
          * RGB rgb = getSystemColor(SWT.COLOR_LIST_SELECTION); // test too light
          * if (testTwoPrimaryColors(rgb, 120, 151)) rgb = blend(rgb, BLACK, 80);
          * else if (testTwoPrimaryColors(rgb, 150, 256)) rgb = blend(rgb, BLACK,
          * 50); createColor(TITLE, rgb);
          */
         RGB bg = getImpliedBackground().getRGB();
         RGB listSelection = getSystemColor(SWT.COLOR_LIST_SELECTION);
         RGB listForeground = getSystemColor(SWT.COLOR_LIST_FOREGROUND);
         RGB rgb = listSelection;

         // Group 1
 // Rule: If at least 2 of the LIST_SELECTION RGB values are equal to or
 // between 0 and 120, then use 100% LIST_SELECTION as it is (no
 // additions)
 // Examples: XP Default, Win Classic Standard, Win High Con White, Win
 // Classic Marine
 if (testTwoPrimaryColors(listSelection, -1, 121))
             rgb = listSelection;
         // Group 2
 // When LIST_BACKGROUND = white (255, 255, 255) or not black, text
 // colour = LIST_SELECTION @ 100% Opacity + 50% LIST_FOREGROUND over
 // LIST_BACKGROUND
 // Rule: If at least 2 of the LIST_SELECTION RGB values are equal to or
 // between 121 and 255, then add 50% LIST_FOREGROUND to LIST_SELECTION
 // foreground colour
 // Examples: Win Vista, XP Silver, XP Olive , Win Classic Plum, OSX
 // Aqua, OSX Graphite, Linux GTK
 else if (testTwoPrimaryColors(listSelection, 120, 256)
                 || (bg.red == 0 && bg.green == 0 && bg.blue == 0))
             rgb = blend(listSelection, listForeground, 50);
         // Group 3
 // When LIST_BACKGROUND = black (0, 0, 0), text colour = LIST_SELECTION
 // @ 100% Opacity + 50% LIST_FOREGROUND over LIST_BACKGROUND
 // Rule: If LIST_BACKGROUND = 0, 0, 0, then add 50% LIST_FOREGROUND to
 // LIST_SELECTION foreground colour
 // Examples: Win High Con Black, Win High Con #1, Win High Con #2
 // (covered in the second part of the OR clause above)
 createColor(IFormColors.TITLE, rgb);
     }

     private void createTwistieColors() {
         RGB rgb = getColor(IFormColors.TITLE).getRGB();
         RGB white = getSystemColor(SWT.COLOR_WHITE);
         createColor(TB_TOGGLE, rgb);
         rgb = blend(rgb, white, 60);
         createColor(TB_TOGGLE_HOVER, rgb);
     }

     private void createTitleBarGradientColors() {
         RGB tbBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
         RGB bg = getImpliedBackground().getRGB();

         // Group 1
 // Rule: If at least 2 of the RGB values are equal to or between 180 and
 // 255, then apply specified opacity for Group 1
 // Examples: Vista, XP Silver, Wn High Con #2
 // Gradient Bottom = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
 // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
 if (testTwoPrimaryColors(tbBg, 179, 256))
             tbBg = blend(tbBg, bg, 30);

         // Group 2
 // Rule: If at least 2 of the RGB values are equal to or between 121 and
 // 179, then apply specified opacity for Group 2
 // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black
 // Gradient Bottom = TITLE_BACKGROUND @ 20% Opacity over LIST_BACKGROUND
 // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
 else if (testTwoPrimaryColors(tbBg, 120, 180))
             tbBg = blend(tbBg, bg, 20);

         // Group 3
 // Rule: Everything else
 // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
 // Aqua, Wn High Con White, Wn High Con #1
 // Gradient Bottom = TITLE_BACKGROUND @ 10% Opacity over LIST_BACKGROUND
 // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
 else {
             tbBg = blend(tbBg, bg, 10);
         }

         createColor(IFormColors.TB_BG, tbBg);
         
         // for backward compatibility
 createColor(TB_GBG, tbBg);
     }

     private void createTitleBarOutlineColors() {
         // title bar outline - border color
 RGB tbBorder = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
         RGB bg = getImpliedBackground().getRGB();
         // Group 1
 // Rule: If at least 2 of the RGB values are equal to or between 180 and
 // 255, then apply specified opacity for Group 1
 // Examples: Vista, XP Silver, Wn High Con #2
 // Keyline = TITLE_BACKGROUND @ 70% Opacity over LIST_BACKGROUND
 if (testTwoPrimaryColors(tbBorder, 179, 256))
             tbBorder = blend(tbBorder, bg, 70);

         // Group 2
 // Rule: If at least 2 of the RGB values are equal to or between 121 and
 // 179, then apply specified opacity for Group 2
 // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black

         // Keyline = TITLE_BACKGROUND @ 50% Opacity over LIST_BACKGROUND
 else if (testTwoPrimaryColors(tbBorder, 120, 180))
             tbBorder = blend(tbBorder, bg, 50);

         // Group 3
 // Rule: Everything else
 // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
 // Aqua, Wn High Con White, Wn High Con #1

         // Keyline = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
 else {
             tbBorder = blend(tbBorder, bg, 30);
         }
         createColor(FormColors.TB_BORDER, tbBorder);
     }

     private void updateFormHeaderColors() {
         if (colorRegistry.containsKey(IFormColors.H_GRADIENT_END)) {
             disposeIfFound(IFormColors.H_GRADIENT_END);
             disposeIfFound(IFormColors.H_GRADIENT_START);
             disposeIfFound(IFormColors.H_BOTTOM_KEYLINE1);
             disposeIfFound(IFormColors.H_BOTTOM_KEYLINE2);
             disposeIfFound(IFormColors.H_HOVER_LIGHT);
             disposeIfFound(IFormColors.H_HOVER_FULL);
             initializeFormHeaderColors();
         }
     }

     private void disposeIfFound(String key) {
         Color color = getColor(key);
         if (color != null) {
             colorRegistry.remove(key);
             color.dispose();
         }
     }

     private void createFormHeaderColors() {
         createFormHeaderGradientColors();
         createFormHeaderKeylineColors();
         createFormHeaderDNDColors();
     }

     private void createFormHeaderGradientColors() {
         RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
         Color bgColor = getImpliedBackground();
         RGB bg = bgColor.getRGB();
         RGB bottom, top;
         // Group 1
 // Rule: If at least 2 of the RGB values are equal to or between 180 and
 // 255, then apply specified opacity for Group 1
 // Examples: Vista, XP Silver, Wn High Con #2
 // Gradient Bottom = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
 // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
 if (testTwoPrimaryColors(titleBg, 179, 256)) {
             bottom = blend(titleBg, bg, 30);
             top = bg;
         }

         // Group 2
 // Rule: If at least 2 of the RGB values are equal to or between 121 and
 // 179, then apply specified opacity for Group 2
 // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black
 // Gradient Bottom = TITLE_BACKGROUND @ 20% Opacity over LIST_BACKGROUND
 // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
 else if (testTwoPrimaryColors(titleBg, 120, 180)) {
             bottom = blend(titleBg, bg, 20);
             top = bg;
         }

         // Group 3
 // Rule: If at least 2 of the RGB values are equal to or between 0 and
 // 120, then apply specified opacity for Group 3
 // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
 // Aqua, Wn High Con White, Wn High Con #1
 // Gradient Bottom = TITLE_BACKGROUND @ 10% Opacity over LIST_BACKGROUND
 // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
 else {
             bottom = blend(titleBg, bg, 10);
             top = bg;
         }
         createColor(IFormColors.H_GRADIENT_END, top);
         createColor(IFormColors.H_GRADIENT_START, bottom);
     }

     private void createFormHeaderKeylineColors() {
         RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
         Color bgColor = getImpliedBackground();
         RGB bg = bgColor.getRGB();
         RGB keyline2;
         // H_BOTTOM_KEYLINE1
 createColor(IFormColors.H_BOTTOM_KEYLINE1, new RGB(255, 255, 255));

         // H_BOTTOM_KEYLINE2
 // Group 1
 // Rule: If at least 2 of the RGB values are equal to or between 180 and
 // 255, then apply specified opacity for Group 1
 // Examples: Vista, XP Silver, Wn High Con #2
 // Keyline = TITLE_BACKGROUND @ 70% Opacity over LIST_BACKGROUND
 if (testTwoPrimaryColors(titleBg, 179, 256))
             keyline2 = blend(titleBg, bg, 70);

         // Group 2
 // Rule: If at least 2 of the RGB values are equal to or between 121 and
 // 179, then apply specified opacity for Group 2
 // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black
 // Keyline = TITLE_BACKGROUND @ 50% Opacity over LIST_BACKGROUND
 else if (testTwoPrimaryColors(titleBg, 120, 180))
             keyline2 = blend(titleBg, bg, 50);

         // Group 3
 // Rule: If at least 2 of the RGB values are equal to or between 0 and
 // 120, then apply specified opacity for Group 3
 // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
 // Aqua, Wn High Con White, Wn High Con #1

         // Keyline = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
 else
             keyline2 = blend(titleBg, bg, 30);
         // H_BOTTOM_KEYLINE2
 createColor(IFormColors.H_BOTTOM_KEYLINE2, keyline2);
     }

     private void createFormHeaderDNDColors() {
         RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT);
         Color bgColor = getImpliedBackground();
         RGB bg = bgColor.getRGB();
         RGB light, full;
         // ALL Themes
 //
 // Light Highlight
 // When *near* the 'hot' area
 // Rule: If near the title in the 'hot' area, show background highlight
 // TITLE_BACKGROUND_GRADIENT @ 40%
 light = blend(titleBg, bg, 40);
         // Full Highlight
 // When *on* the title area (regions 1 and 2)
 // Rule: If near the title in the 'hot' area, show background highlight
 // TITLE_BACKGROUND_GRADIENT @ 60%
 full = blend(titleBg, bg, 60);
         // H_DND_LIGHT
 // H_DND_FULL
 createColor(IFormColors.H_HOVER_LIGHT, light);
         createColor(IFormColors.H_HOVER_FULL, full);
     }
 }

